# API 参考

> 在以下文档中，你可能会看到带有 `agent.` 前缀的函数调用。如果你在 Playwright 中，这些调用是不带 `agent.` 前缀的，如 `async ({ ai, aiQuery }) => { /* ... */}`。这只是解构语法的区别。

## 构造器

Midscene 中每个 Agent 都有自己的构造函数。

- 在 Puppeteer 中，使用 [PuppeteerAgent](./integrate-with-puppeteer)
- 在桥接模式（Bridge Mode）中，使用 [AgentOverChromeBridge](./bridge-mode-by-chrome-extension#constructor)
- 在 Android 中，使用 [AndroidAgent](./integrate-with-android)
- 如果你为自定义界面创建 GUI Agent，请参考 [集成到任意界面](./integrate-with-any-interface)

这些 Agent 有一些相同的构造参数：

- `generateReport: boolean`: 如果为 true，则生成报告文件。默认值为 true。
- `reportFileName: string`: 报告文件的名称，默认值由 midscene 内部生成。
- `autoPrintReportMsg: boolean`: 如果为 true，则打印报告消息。默认值为 true。
- `cacheId: string | undefined`: 如果配置，则使用此 cacheId 保存或匹配缓存。默认值为 undefined，也就是不启用缓存。
- `actionContext: string`: 调用 `agent.aiAction()` 时，发送给 AI 模型的背景知识，比如 '有 cookie 对话框时先关闭它'，默认值为空。
- `onTaskStartTip: (tip: string) => void | Promise<void>`：可选回调，在每个子任务执行开始前收到一条可读的任务描述提示。默认值为 undefined。

在 Playwright 和 Puppeteer 中，有以下共同的参数：

- `forceSameTabNavigation: boolean`: 如果为 true，则限制页面在当前 tab 打开。默认值为 true。
- `waitForNavigationTimeout: number`: 在页面跳转后等待页面加载完成的超时时间，默认值为 5000ms，设置为 0 则不做等待。

在 Puppeteer 中，还有以下参数：

- `waitForNetworkIdleTimeout: number`: 在执行每个操作后等待网络空闲的超时时间，默认值为 2000ms，设置为 0 则不做等待。

## 交互方法

这些是 Midscene 中各类 Agent 的主要 API。

:::info 自动规划 v.s. 即时操作

在 Midscene 中，你可以选择使用自动规划（Auto Planning）或即时操作（Instant Action）。

- `agent.ai()` 是自动规划（Auto Planning）：Midscene 会自动规划操作步骤并执行。它更智能，更像流行的 AI Agent 风格，但可能较慢，且效果依赖于 AI 模型的质量。
- `agent.aiTap()`, `agent.aiHover()`, `agent.aiInput()`, `agent.aiKeyboardPress()`, `agent.aiScroll()`, `agent.aiDoubleClick()`, `agent.aiRightClick()` 是即时操作（Instant Action）：Midscene 会直接执行指定的操作，而 AI 模型只负责底层任务，如定位元素等。这种接口形式更快、更可靠。当你完全确定自己想要执行的操作时，推荐使用这种接口形式。

:::

### `agent.aiAction()` 或 `.ai()`

这个方法允许你通过自然语言描述一系列 UI 操作步骤。Midscene 会自动规划这些步骤并执行。

- 类型

```typescript
function aiAction(
  prompt: string,
  options?: {
    cacheable?: boolean;
  },
): Promise<void>;
function ai(prompt: string): Promise<void>; // 简写形式
```

- 参数：

  - `prompt: string` - 用自然语言描述的操作内容
  - `options?: Object` - 可选，一个配置对象，包含：
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true

- 返回值：

  - 返回一个 Promise。当所有步骤执行完成时解析为 void；若执行失败，则抛出错误。

- 示例：

```typescript
// 基本用法
await agent.aiAction('在搜索框中输入 "JavaScript"，然后点击搜索按钮');

// 使用 .ai 简写形式
await agent.ai(
  '点击页面顶部的登录按钮，然后在用户名输入框中输入 "test@example.com"',
);

// 使用 ui-tars 模型时，可以使用更目标驱动的提示词
await agent.aiAction('发布一条微博，内容为 "Hello World"');
```

:::tip

在实际运行时，Midscene 会将用户指令规划（Planning）成多个步骤，然后逐步执行。如果 Midscene 认为无法执行，将抛出一个错误。

为了获得最佳效果，请尽可能提供清晰、详细的步骤描述。具体可以参考这篇文档：[编写提示词的技巧](./prompting-tips)

关联文档：

- [选择 AI 模型](./choose-a-model)

:::

### `agent.aiTap()`

点击某个元素。

- 类型

```typescript
function aiTap(locate: string | Object, options?: Object): Promise<void>;
```

- 参数：
  - `locate: string | Object` - 用自然语言描述的元素定位，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `deepThink?: boolean` - 是否开启深度思考。如果为 true，Midscene 会调用 AI 模型两次以精确定位元素。默认值为 false
    - `xpath?: string` - 目标元素的 xpath 路径，用于执行当前操作。如果提供了这个 xpath，Midscene 会优先使用该 xpath 来找到元素，然后依次使用缓存和 AI 模型。默认值为空
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true
- 返回值：

  - `Promise<void>`

- 示例：

```typescript
await agent.aiTap('页面顶部的登录按钮');

// 使用 deepThink 功能精确定位元素
await agent.aiTap('页面顶部的登录按钮', { deepThink: true });
```

### `agent.aiHover()`

> 仅在 web 页面中可用，在 Android 下不可用

鼠标悬停某个元素上。

- 类型

```typescript
function aiHover(locate: string | Object, options?: Object): Promise<void>;
```

- 参数：
  - `locate: string | Object` - 用自然语言描述的元素定位，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `deepThink?: boolean` - 是否开启深度思考。如果为 true，Midscene 会调用 AI 模型两次以精确定位元素。默认值为 false
    - `xpath?: string` - 目标元素的 xpath 路径，用于执行当前操作。如果提供了这个 xpath，Midscene 会优先使用该 xpath 来找到元素，然后依次使用缓存和 AI 模型。默认值为空
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true
- 返回值：

  - `Promise<void>`

- 示例：

```typescript
await agent.aiHover('页面顶部的登录按钮');
```

### `agent.aiInput()`

在某个元素中输入文本。

- 类型

```typescript
function aiInput(
  text: string | Object,
  locate: string,
  options?: Object,
): Promise<void>;
```

- 参数：

  - `text: string` - 要输入的文本内容。使用空字符串可以清空输入框。
  - `locate: string | Object` - 用自然语言描述的元素定位，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `deepThink?: boolean` - 是否开启深度思考。如果为 true，Midscene 会调用 AI 模型两次以精确定位元素。默认值为 false
    - `xpath?: string` - 目标元素的 xpath 路径，用于执行当前操作。如果提供了这个 xpath，Midscene 会优先使用该 xpath 来找到元素，然后依次使用缓存和 AI 模型。默认值为空
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true
    - `autoDismissKeyboard?: boolean` - 如果为 true，则键盘会在输入文本后自动关闭，仅在 Android 中有效。默认值为 true。

- 返回值：

  - `Promise<void>`

- 示例：

```typescript
await agent.aiInput('Hello World', '搜索框');
```

### `agent.aiKeyboardPress()`

按下键盘上的某个键。

- 类型

```typescript
function aiKeyboardPress(
  key: string,
  locate?: string | Object,
  options?: Object,
): Promise<void>;
```

- 参数：

  - `key: string` - 要按下的键，如 `Enter`、`Tab`、`Escape` 等。不支持组合键。
  - `locate?: string | Object` - 用自然语言描述的元素定位，，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `deepThink?: boolean` - 是否开启深度思考。如果为 true，Midscene 会调用 AI 模型两次以精确定位元素。默认值为 false
    - `xpath?: string` - 目标元素的 xpath 路径，用于执行当前操作。如果提供了这个 xpath，Midscene 会优先使用该 xpath 来找到元素，然后依次使用缓存和 AI 模型。默认值为空
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true

- 返回值：

  - `Promise<void>`

- 示例：

```typescript
await agent.aiKeyboardPress('Enter', '搜索框');
```

### `agent.aiScroll()`

滚动页面或某个元素。

- 类型

```typescript
function aiScroll(
  scrollParam: PlanningActionParamScroll,
  locate?: string | Object,
  options?: Object,
): Promise<void>;
```

- 参数：

  - `scrollParam: PlanningActionParamScroll` - 滚动参数
    - `direction: 'up' | 'down' | 'left' | 'right'` - 滚动方向。不论是 Android 还是 Web，这里的滚动方向都是指页面哪个方向的内容会进入屏幕。比如当滚动方向是 `down` 时，页面下方被隐藏的内容会从屏幕底部开始逐渐向上露出。
    - `scrollType: 'once' | 'untilBottom' | 'untilTop' | 'untilRight' | 'untilLeft'` - 滚动类型
    - `distance: number` - 滚动距离，单位为像素。
  - `locate?: string | Object` - 用自然语言描述的元素定位，或[使用图片作为提示词](#使用图片作为提示词)。如果未传入，Midscene 会在当前鼠标位置滚动。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `deepThink?: boolean` - 是否开启深度思考。如果为 true，Midscene 会调用 AI 模型两次以精确定位元素。默认值为 false
    - `xpath?: string` - 目标元素的 xpath 路径，用于执行当前操作。如果提供了这个 xpath，Midscene 会优先使用该 xpath 来找到元素，然后依次使用缓存和 AI 模型。默认值为空
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true

- 返回值：

  - `Promise<void>`

- 示例：

```typescript
await agent.aiScroll(
  { direction: 'up', distance: 100, scrollType: 'once' },
  '表单区域',
);
```

### `agent.aiDoubleClick()`

双击某个元素。

- 类型

```typescript
function aiDoubleClick(locate: string | Object, options?: Object): Promise<void>;
```

- 参数：

  - `locate: string | Object` - 用自然语言描述的元素定位，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `deepThink?: boolean` - 是否开启深度思考。如果为 true，Midscene 会调用 AI 模型两次以精确定位元素。默认值为 false
    - `xpath?: string` - 目标元素的 xpath 路径，用于执行当前操作。如果提供了这个 xpath，Midscene 会优先使用该 xpath 来找到元素，然后依次使用缓存和 AI 模型。默认值为空
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true

- 返回值：

  - `Promise<void>`

- 示例：

```typescript
await agent.aiDoubleClick('页面顶部的文件名称');

// 使用 deepThink 功能精确定位元素
await agent.aiDoubleClick('页面顶部的文件名称', { deepThink: true });
```

### `agent.aiRightClick()`

> 仅在 web 页面中可用，在 Android 下不可用

右键点击某个元素。请注意，Midscene 在右键点击后无法与浏览器原生上下文菜单交互。这个接口通常用于已经监听了右键点击事件的元素。

- 类型

```typescript
function aiRightClick(locate: string | Object, options?: Object): Promise<void>;
```

- 参数：

  - `locate: string | Object` - 用自然语言描述的元素定位，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `deepThink?: boolean` - 是否开启深度思考。如果为 true，Midscene 会调用 AI 模型两次以精确定位元素。默认值为 false
    - `xpath?: string` - 目标元素的 xpath 路径，用于执行当前操作。如果提供了这个 xpath，Midscene 会优先使用该 xpath 来找到元素，然后依次使用缓存和 AI 模型。默认值为空
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true

- 返回值：

  - `Promise<void>`

- 示例：

```typescript
await agent.aiRightClick('页面顶部的文件名称');

// 使用 deepThink 功能精确定位元素
await agent.aiRightClick('页面顶部的文件名称', { deepThink: true });
```

:::tip 关于 `deepThink` （深度思考）特性

`deepThink` 是一个强大的特性，它允许 Midscene 调用 AI 模型两次以精确定位元素。这在目标元素面积较小、难以和周围元素区分时非常有用。

:::

## 数据提取

### `agent.aiAsk()`

使用此方法，你可以针对当前页面，直接向 AI 模型发起提问，并获得字符串形式的回答。

- 类型

```typescript
function aiAsk(prompt: string | Object, options?: Object): Promise<string>;
```

- 参数：

  - `prompt: string | Object` - 用自然语言描述的询问内容，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `domIncluded?: boolean | 'visible-only'` - 是否向模型发送精简后的 DOM 信息，一般用于提取 UI 中不可见的属性，比如图片的链接。如果设置为 `'visible-only'`，则只发送可见的元素。默认值为 false。
    - `screenshotIncluded?: boolean` - 是否向模型发送截图。默认值为 true。

- 返回值：

  - 返回一个 Promise。返回 AI 模型的回答。

- 示例：

```typescript
const result = await agent.aiAsk('当前页面的应该怎么进行测试？');
console.log(result); // 输出 AI 模型的回答
```

除了 `aiAsk` 方法，你还可以使用 `aiQuery` 方法，直接从 UI 提取结构化的数据。

### `agent.aiQuery()`

使用此方法，你可以直接从 UI 提取结构化的数据。只需在 `dataDemand` 中描述期望的数据格式（如字符串、数字、JSON、数组等），Midscene 即返回相应结果。

- 类型

```typescript
function aiQuery<T>(dataDemand: string | Object, options?: Object): Promise<T>;
```

- 参数：

  - `dataDemand: T`: 描述预期的返回值和格式。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `domIncluded?: boolean | 'visible-only'` - 是否向模型发送精简后的 DOM 信息，一般用于提取 UI 中不可见的属性，比如图片的链接。如果设置为 `'visible-only'`，则只发送可见的元素。默认值为 false。
    - `screenshotIncluded?: boolean` - 是否向模型发送截图。默认值为 true。

- 返回值：

  - 返回值可以是任何合法的基本类型，比如字符串、数字、JSON、数组等。
  - 你只需在 `dataDemand` 中描述它，Midscene 就会给你满足格式的返回。

- 示例：

```typescript
const dataA = await agent.aiQuery({
  time: '左上角展示的日期和时间，string',
  userInfo: '用户信息，{name: string}',
  tableFields: '表格的字段名，string[]',
  tableDataRecord: '表格中的数据记录，{id: string, [fieldName]: string}[]',
});

// 你也可以用纯字符串描述预期的返回值格式：

// dataB 将是一个字符串数组
const dataB = await agent.aiQuery('string[]，列表中的任务名称');

// dataC 将是一个包含对象的数组
const dataC = await agent.aiQuery(
  '{name: string, age: string}[], 表格中的数据记录',
);

// 使用 domIncluded 功能提取 UI 中不可见的属性
const dataD = await agent.aiQuery(
  '{name: string, age: string, avatarUrl: string}[], 表格中的数据记录',
  { domIncluded: true },
);
```

此外，我们还提供了 `aiBoolean()`, `aiNumber()`, `aiString()` 三个便捷方法，用于直接提取布尔值、数字和字符串。

### `agent.aiBoolean()`

从 UI 中提取一个布尔值。

- 类型

```typescript
function aiBoolean(prompt: string | Object, options?: Object): Promise<boolean>;
```

- 参数：

  - `prompt: string` - 用自然语言描述的期望值，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `domIncluded?: boolean | 'visible-only'` - 是否向模型发送精简后的 DOM 信息，一般用于提取 UI 中不可见的属性，比如图片的链接。如果设置为 `'visible-only'`，则只发送可见的元素。默认值为 false。
    - `screenshotIncluded?: boolean` - 是否向模型发送截图。默认值为 true。

- 返回值：

  - 返回一个 Promise。当 AI 返回结果时解析为布尔值。

- 示例：

```typescript
const boolA = await agent.aiBoolean('是否存在登录对话框');

// 使用 domIncluded 功能提取 UI 中不可见的属性
const boolB = await agent.aiBoolean('忘记密码按钮是否存在链接', {
  domIncluded: true,
});
```

### `agent.aiNumber()`

从 UI 中提取一个数字。

- 类型

```typescript
function aiNumber(prompt: string | Object, options?: Object): Promise<number>;
```

- 参数：

  - `prompt: string | Object` - 用自然语言描述的期望值，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `domIncluded?: boolean | 'visible-only'` - 是否向模型发送精简后的 DOM 信息，一般用于提取 UI 中不可见的属性，比如图片的链接。如果设置为 `'visible-only'`，则只发送可见的元素。默认值为 false。
    - `screenshotIncluded?: boolean` - 是否向模型发送截图。默认值为 true。

- 返回值：

  - 返回一个 Promise。当 AI 返回结果时解析为数字。

- 示例：

```typescript
const numberA = await agent.aiNumber('账户剩余的积分');

// 使用 domIncluded 功能提取 UI 中不可见的属性
const numberB = await agent.aiNumber('账户剩余的积分元素的 value 值', {
  domIncluded: true,
});
```

### `agent.aiString()`

从 UI 中提取一个字符串。

- 类型

```typescript
function aiString(prompt: string | Object, options?: Object): Promise<string>;
```

- 参数：

  - `prompt: string | Object` - 用自然语言描述的期望值，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `domIncluded?: boolean | 'visible-only'` - 是否向模型发送精简后的 DOM 信息，一般用于提取 UI 中不可见的属性，比如图片的链接。如果设置为 `'visible-only'`，则只发送可见的元素。默认值为 false。
    - `screenshotIncluded?: boolean` - 是否向模型发送截图。默认值为 true。

- 返回值：

  - 返回一个 Promise。当 AI 返回结果时解析为字符串。

- 示例：

```typescript
const stringA = await agent.aiString('当前列表的第一条记录的名称');

// 使用 domIncluded 功能提取 UI 中不可见的属性
const stringB = await agent.aiString('当前列表的第一条记录的跳转链接', {
  domIncluded: true,
});
```

## 更多方法

### `agent.aiAssert()`

通过自然语言描述一个断言条件，让 AI 判断该条件是否为真。当条件不满足时，SDK 会抛出错误，并在错误信息中追加 AI 返回的详细原因。

- 类型

```typescript
function aiAssert(
  assertion: string | Object, 
  errorMsg?: string, 
  options?: Object
): Promise<void>;
```

- 参数：

  - assertion: string | Object - 用自然语言描述的断言条件，或[使用图片作为提示词](#使用图片作为提示词)。
  - errorMsg?: string - 当断言失败时附加的可选错误提示信息。
  - options?: Object - 可选，一个配置对象，包含：
    - `domIncluded?: boolean | 'visible-only'` - 是否向模型发送精简后的 DOM 信息，一般用于提取 UI 中不可见的属性，比如图片的链接。如果设置为 `'visible-only'`，则只发送可见的元素。默认值为 false。
    - `screenshotIncluded?: boolean` - 是否向模型发送截图。默认值为 true。

- 返回值：

  - 返回一个 Promise。当断言成功时解析为 void；若断言失败，则抛出一个错误，错误信息包含 `errorMsg` 以及 AI 生成的原因。

- 示例：

```typescript
await agent.aiAssert('"Sauce Labs Onesie" 的价格是 7.99');
```

:::tip
断言在测试脚本中非常重要。为了降低因 AI 幻觉导致错误断言的风险（例如遗漏错误），你也可以使用 `.aiQuery` 加上常规的 JavaScript 断言来替代 `.aiAssert`。

例如，你可以这样替代上面的断言代码：

```typescript
const items = await agent.aiQuery(
  '"{name: string, price: number}[], 返回商品名称和价格列表',
);
const onesieItem = items.find((item) => item.name === 'Sauce Labs Onesie');
expect(onesieItem).toBeTruthy();
expect(onesieItem.price).toBe(7.99);
```

:::

### `agent.aiLocate()`

通过自然语言描述一个元素的定位。

- 类型

```typescript
function aiLocate(
  locate: string | Object,
  options?: Object,
): Promise<{
  rect: {
    left: number;
    top: number;
    width: number;
    height: number;
  };
  center: [number, number];
  scale: number; // device pixel ratio
}>;
```

- 参数：

  - `locate: string | Object` - 用自然语言描述的元素定位，或[使用图片作为提示词](#使用图片作为提示词)。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `deepThink?: boolean` - 是否开启深度思考。如果为 true，Midscene 会调用 AI 模型两次以精确定位元素。默认值为 false
    - `xpath?: string` - 目标元素的 xpath 路径，用于执行当前操作。如果提供了这个 xpath，Midscene 会优先使用该 xpath 来找到元素，然后依次使用缓存和 AI 模型。默认值为空
    - `cacheable?: boolean` - 当启用 [缓存功能](./caching.mdx) 时，是否允许缓存当前 API 调用结果。默认值为 true

- 返回值：

  - 返回一个 Promise。当元素定位成功时解析为元素定位信息。

- 示例：

```typescript
const locateInfo = await agent.aiLocate('页面顶部的登录按钮');
console.log(locateInfo);
```

### `agent.aiWaitFor()`

等待某个条件达成。考虑到 AI 服务的成本，检查间隔不会超过 `checkIntervalMs` 毫秒。

- 类型

```typescript
function aiWaitFor(
  assertion: string,
  options?: {
    timeoutMs?: number;
    checkIntervalMs?: number;
  },
): Promise<void>;
```

- 参数：

  - `assertion: string` - 用自然语言描述的断言条件
  - `options?: object` - 可选的配置对象
    - `timeoutMs?: number` - 超时时间（毫秒），默认为 15000
    - `checkIntervalMs?: number` - 检查间隔（毫秒），默认为 3000

- 返回值：

  - 返回一个 Promise。当断言成功时解析为 void；若超时，则抛出错误。

- 示例：

```typescript
// 基本用法
await agent.aiWaitFor('界面上至少有一个耳机的信息');

// 使用自定义配置
await agent.aiWaitFor('购物车图标显示数量为 2', {
  timeoutMs: 30000, // 等待 30 秒
  checkIntervalMs: 5000, // 每 5 秒检查一次
});
```

:::tip
考虑到 AI 服务的时间消耗，`.aiWaitFor` 并不是一个特别高效的方法。使用一个普通的 `sleep` 可能是替代 `waitFor` 的另一种方式。
:::

### `agent.runYaml()`

执行一个 YAML 格式的自动化脚本。脚本中的 `tasks` 部分会被执行，并返回所有 `.aiQuery` 调用的结果。

- 类型

```typescript
function runYaml(yamlScriptContent: string): Promise<{ result: any }>;
```

- 参数：

  - `yamlScriptContent: string` - YAML 格式的脚本内容

- 返回值：

  - 返回一个包含 `result` 属性的对象，其中包含所有 `aiQuery` 调用的结果

- 示例：

```typescript
const { result } = await agent.runYaml(`
tasks:
  - name: search weather
    flow:
      - ai: input 'weather today' in input box, click search button
      - sleep: 3000

  - name: query weather
    flow:
      - aiQuery: "the result shows the weather info, {description: string}"
`);
console.log(result);
```

:::tip
更多关于 YAML 脚本的信息，请参考 [Automate with Scripts in YAML](./automate-with-scripts-in-yaml)。
:::

### `agent.setAIActionContext()`

设置在调用 `agent.aiAction()` 或 `agent.ai()` 时，发送给 AI 模型的背景知识。这个设置会覆盖之前的设置。

对于即时操作类型的 API，比如 `aiTap()`，这个设置不会生效。

- 类型

```typescript
function setAIActionContext(actionContext: string): void;
```

- 参数：

  - `actionContext: string` - 要发送给 AI 模型的背景知识。

- 示例：

```typescript
await agent.setAIActionContext('如果 “使用cookie” 对话框存在，先关闭它');
```

### `agent.evaluateJavaScript()`

> 仅在 web 页面中可用，在 Android 下不可用

这个方法允许你在 web 页面上下文中执行一段 JavaScript 代码，并返回执行结果。

- 类型

```typescript
function evaluateJavaScript(script: string): Promise<any>;
```

- 参数：

  - `script: string` - 要执行的 JavaScript 代码。

- 返回值：

  - 返回执行结果。

- 示例：

```typescript
const result = await agent.evaluateJavaScript('document.title');
console.log(result);
```

### `agent.logScreenshot()`

在报告文件中记录当前截图，并添加描述。

- 类型

```typescript
function logScreenshot(title?: string, options?: Object): Promise<void>;
```

- 参数：

  - `title?: string` - 可选，截图的标题，如果未提供，则标题为 'untitled'。
  - `options?: Object` - 可选，一个配置对象，包含：
    - `content?: string` - 截图的描述。

- 返回值：

  - `Promise<void>`

- 示例：

```typescript
await agent.logScreenshot('登录页面', {
  content: '用户 A',
});
```

### `agent.freezePageContext()`

冻结当前页面上下文，使后续所有的操作都复用同一个页面快照，避免多次重复获取页面状态。在执行大量并发操作时，它可以显著提升性能。

一些注意点：
* 通常情况下，你不需要使用这个方法，除非你确定“页面状态获取”是脚本性能瓶颈。
* 需要及时调用 `agent.unfreezePageContext()` 来恢复实时页面状态。
* 不要在交互类操作中使用这个方法，它会让 AI 模型无法感知到页面的最新状态，产生令人困惑的错误。

- 类型

```typescript
function freezePageContext(): Promise<void>;
```

- 返回值：

  - `Promise<void>`

- 示例：

```typescript
// 冻结页面上下文，确保多个操作看到相同的页面状态
await agent.freezePageContext();

// 执行一些操作...
const results = await Promise.all([
  await agent.aiQuery('Username input box value'),
  await agent.aiQuery('Password input box value'),
  await agent.aiLocate('Login button'),
]);
console.log(results);

// 解冻页面上下文
await agent.unfreezePageContext();
```

:::tip
在报告中，使用冻结上下文的操作会在 Insight tab 中显示 🧊 图标。
:::

### `agent.unfreezePageContext()`

解冻页面上下文，恢复使用实时的页面状态。

- 类型

```typescript
function unfreezePageContext(): Promise<void>;
```

- 返回值：

  - `Promise<void>`

### `agent._unstableLogContent()`

从报告文件中获取日志内容。日志内容的结构可能会在未来发生变化。

- 类型

```typescript
function _unstableLogContent(): Object;
```

- 返回值：

  - 返回一个对象，包含日志内容。

- 示例：

```typescript
const logContent = agent._unstableLogContent();
console.log(logContent);
```

## 属性

### `.reportFile`

报告文件的路径。

## 更多配置

### 在运行时设置环境变量

你可以通过 `overrideAIConfig` 方法在运行时设置环境变量。

```typescript
import { overrideAIConfig } from '@midscene/web/puppeteer'; // 或其他的 Agent

overrideAIConfig({
  OPENAI_BASE_URL: '...',
  OPENAI_API_KEY: '...',
  MIDSCENE_MODEL_NAME: '...',
});
```

### 打印 AI 性能信息

设置 `DEBUG=midscene:ai:profile:stats` 环境变量，你可以看到每次调用 AI 的时间和 token 数量。

```bash
export DEBUG=midscene:ai:profile:stats
```

### 自定义运行产物目录

设置 `MIDSCENE_RUN_DIR` 变量，你可以自定义运行产物目录。

```bash
export MIDSCENE_RUN_DIR=midscene_run # 默认值为当前运行目录下的 midscene_run 目录，支持设置为绝对路径或者相对于当前目录的相对路径
```

### 自定义重新规划循环限制

设置 `MIDSCENE_REPLANNING_CYCLE_LIMIT` 变量，你可以自定义在执行操作(`aiAction`)时允许的最大重新规划循环次数。

```bash
export MIDSCENE_REPLANNING_CYCLE_LIMIT=10 # 默认值为 10。当 AI 需要重新规划超过这个限制时，会抛出错误建议将任务拆分为多个步骤
```

### 使用 LangSmith

LangSmith 是一个用于调试大语言模型的平台。想要集成 LangSmith，请按以下步骤操作：

```bash
# 设置环境变量

# 启用调试标志
export MIDSCENE_LANGSMITH_DEBUG=1

# LangSmith 配置
export LANGSMITH_TRACING_V2=true
export LANGSMITH_ENDPOINT="https://api.smith.langchain.com"
export LANGSMITH_API_KEY="your_key_here"
export LANGSMITH_PROJECT="your_project_name_here"
```

启动 Midscene 后，你应该会看到类似如下的日志：

```log
DEBUGGING MODE: langsmith wrapper enabled
```

## 高级功能

### 使用图片作为提示词

你可以在提示词中使用图片作为补充，来描述无法通过自然语言表达的内容。

使用图片作为提示词时，提示词的参数格式如下：

```javascript
{
  // 提示词文本，其中可提及需要使用的图片
  prompt: string,
  // 提示词中提到的图片
  images?: {
    // 图片名称，需要和提示词文本中提到的图片名称对应
    name: string,
    // 图片 url，可以是本地图片路径、Base64 字符串，或者图片的 http 链接
    url: string
  }[]
  // 开启该选项后，http 格式的图片链接会被转化为 Base64 编码发送给大模型，适用于图片链接不是公开可访问的情况。
  convertHttpImage2Base64?: boolean
}
```

- 示例一：使用图片描述点击位置

```javascript
await agent.aiTap({
  prompt: '指定 logo',
  images: [
    {
      name: '指定 logo',
      url: 'https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png',
    },
  ],
});
```

- 示例二：使用图片进行页面断言

```javascript
await agent.aiAssert({
  prompt: '页面上是否存在指定 logo',
  images: [
    {
      name: '指定 logo',
      url: 'https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png',
    },
  ],
});
```

**图片尺寸的注意事项**

在提示词中使用图片时，可能需要关注模型提供商对图片体积和尺寸的要求，过大（比如超过 10M）或过小（比如小于 10 像素）的图片都有可能导致模型调用时出现报错，具体的限制请以你所使用模型提供商的文档为准。
